#include "BlockQueue.hpp"
#include "Task.hpp"
#include <ctime>

#define TNUM 5

void* consumer(void* args)
{
    BlockQueue<Task>* bqueue = (BlockQueue<Task>*)args;
    // 消费
    while (true)
    {
        // 获取任务
        Task t;
        bqueue->pop(&t); 
        // 完成任务
        cout << pthread_self() << ", 消费者: " << t._x << " + " << t._y << " = " << t() << endl;
        sleep(1);
    }

    return nullptr;
}

int Add(int x, int y)
{
    return x + y;
}

void* productor(void* args)
{
    BlockQueue<Task>* bqueue = (BlockQueue<Task>*)args;
    // 生产
    while (true)
    {
        // 制作任务
        int x = rand() % 10 + 1;
        usleep(rand()%1000); // 不要让两个数一样
        int y = rand() % 10 + 1;
        Task t(x, y, Add);

        bqueue->push(t);

        cout << pthread_self() << ", 生产者: " << t._x << " + " << t._y << " = ? " << endl;
        sleep(1);
    }

    return nullptr;
}

int main()
{
    srand((unsigned)time(nullptr) ^ getpid());

    BlockQueue<Task>* bqueue = new BlockQueue<Task>();

    // 生产者 消费者
    pthread_t c[TNUM], p[TNUM];

    // 创建
    for (int i = 0; i < TNUM; i++)
    {
        pthread_create(c + i, nullptr, consumer, (void*)bqueue);
        pthread_create(p + i, nullptr, productor, (void*)bqueue);
    }

    // 等待
    for (int i = 0; i < TNUM; i++)
    {
        pthread_join(c[i], nullptr);
        pthread_join(p[i], nullptr);
    }

    return 0;
}